using Microsoft.Xna.Framework.Input;
using System;
namespace Tomahawk.Runtime.Input.Pattern
{
    public class PGamePadState
    {
        public bool IsConnected;
        public PGamePadButtons Buttons;
        public PGamePadDPad DPad;
        public PGamePadThumbSticks ThumbSticks;
        public PGamePadTriggers Triggers;

        public PGamePadState()
        {
            IsConnected = true;
            Buttons.A = PButtonState.Undefined;
            Buttons.B = PButtonState.Undefined;
            Buttons.Back = PButtonState.Undefined;
            Buttons.LeftShoulder = PButtonState.Undefined;
            Buttons.LeftStick = PButtonState.Undefined;
            Buttons.RightShoulder = PButtonState.Undefined;
            Buttons.RightStick = PButtonState.Undefined;
            Buttons.Start = PButtonState.Undefined;
            Buttons.X = PButtonState.Undefined;
            Buttons.Y = PButtonState.Undefined;

            DPad.Down = PButtonState.Undefined;
            DPad.Left = PButtonState.Undefined;
            DPad.Right = PButtonState.Undefined;
            DPad.Up = PButtonState.Undefined;

            ThumbSticks.Left.X = null;
            ThumbSticks.Left.Y = null;
            ThumbSticks.Right.X = null;
            ThumbSticks.Right.Y = null;

            Triggers.Left = null;
            Triggers.Right = null;
        }
        public override int GetHashCode()
        {
 	         return Buttons.GetHashCode() ^ DPad.GetHashCode() ^ IsConnected.GetHashCode() ^ ThumbSticks.GetHashCode() ^ Triggers.GetHashCode();
        }

        public override bool Equals(Object obj)
        {
            GamePadState state;

            //Check for null and compare run-time types.
            if (obj == null) return false;

            try
            {
                state = (GamePadState)obj;
            }
            catch (Exception)
            {
                return false;
            }

            //If a state in a pattern is no connected and the state is not
            //connected, then the states match
            if (!state.IsConnected && !this.IsConnected) return true;
            
            //the state is not equal to the pattern
            if (state.IsConnected != this.IsConnected) return false;
            
            //state and pattern connected then...

            //buttons. If not undefined, then compare
            if (Buttons.A != PButtonState.Undefined && (int)Buttons.A != (int)state.Buttons.A) return false;
            if (Buttons.B != PButtonState.Undefined && (int)Buttons.B != (int)state.Buttons.B) return false;
            if (Buttons.Back != PButtonState.Undefined && (int)Buttons.Back != (int)state.Buttons.Back) return false;
            if (Buttons.LeftShoulder != PButtonState.Undefined && (int)Buttons.LeftShoulder != (int)state.Buttons.LeftShoulder) return false;
            if (Buttons.LeftStick != PButtonState.Undefined && (int)Buttons.LeftStick != (int)state.Buttons.LeftStick) return false;
            if (Buttons.RightShoulder != PButtonState.Undefined && (int)Buttons.RightShoulder != (int)state.Buttons.RightShoulder) return false;
            if (Buttons.RightStick != PButtonState.Undefined && (int)Buttons.RightStick != (int)state.Buttons.RightStick) return false;
            if (Buttons.Start != PButtonState.Undefined && (int)Buttons.Start != (int)state.Buttons.Start) return false;
            if (Buttons.X != PButtonState.Undefined && (int)Buttons.X != (int)state.Buttons.X) return false;
            if (Buttons.Y != PButtonState.Undefined && (int)Buttons.Y != (int)state.Buttons.Y) return false;

            //dpad. If not undefined, then compare
            if (DPad.Down != PButtonState.Undefined && (int)DPad.Down != (int)state.DPad.Down) return false;
            if (DPad.Left != PButtonState.Undefined && (int)DPad.Left != (int)state.DPad.Left) return false;
            if (DPad.Right != PButtonState.Undefined && (int)DPad.Right != (int)state.DPad.Right) return false;
            if (DPad.Up != PButtonState.Undefined && (int)DPad.Up != (int)state.DPad.Up) return false;

            //Thumbsticks
            if (ThumbSticks.Left.X.HasValue && (float)ThumbSticks.Left.X != state.ThumbSticks.Left.X) return false;
            if (ThumbSticks.Left.Y.HasValue && (float)ThumbSticks.Left.Y != state.ThumbSticks.Left.Y) return false;

            if (ThumbSticks.Right.X.HasValue && (float)ThumbSticks.Right.X != state.ThumbSticks.Right.X) return false;
            if (ThumbSticks.Right.Y.HasValue && (float)ThumbSticks.Right.Y != state.ThumbSticks.Right.Y) return false;

            //Triggers
            if (Triggers.Left.HasValue && Triggers.Left != state.Triggers.Left) return false;
            if (Triggers.Right.HasValue && Triggers.Right != state.Triggers.Right) return false;

            //if all above is the same the they're equals
            return true;
        }
    }
}
